import pandas as pd
import numpy as np


# 读取CSV
def _csv():
    """
    CSV（Comma-Separated Values）是用逗号分隔值的数据形式，
    有时也称为字符分隔值，因为分隔字符也可以不是逗号。
    CSV文件的一般文件扩展名为.csv，用制表符号分隔也常用.tsv作为扩展名。
    CSV不仅可以是一个实体文件，还可以是字符形式，以便于在网络上传输。
    """
    # 文件目录
    pd.read_csv('data.csv')  # 如果文件与代码文件在同一目录下
    pd.read_csv('data/my/data.csv')  # 指定目录
    pd.read_csv('data/my/my.data')  # CSV文件的扩展名不一定是.csv
    # 使用URL
    pd.read_csv('https://www.gairuo.com/file/data/dataset/GDP-China.csv')
    
    # 可以传数据字符串，即CSV中的数据字符以字符串形式直接传入
    from io import StringIO
    data = ('col1,col2,col3\n'
            'a,b,1\n'
            'a,b,2\n'
            'c,d,3')
    pd.read_csv(StringIO(data))
    pd.read_csv(StringIO(data), dtype=object)
    
    # 也可以传入字节数据
    from io import BytesIO
    data = (b'word,length\n'
            b'Tr\xc3\xa4umen,7\n'
            b'Gr\xc3\xbc\xc3\x9fe,5')
    pd.read_csv(BytesIO(data))
    pd.read_csv(BytesIO(data), dtype=object)


# 读取Excel
def _excel():
    """
    Excel缺点
    1.无法进行复杂的处理
        有时Excel提供的函数和处理方法无法满足复杂逻辑。
    2.无法支持更大的数据量
        目前Excel支持的行数上限为 1 048 576（2的20次方），列数上限为 16 384（2的14次方，列标签为XFD），在数据分析、机器学习操作中往往会超过这个体量。
    3.处理方法无法复用
        Excel一般采用设定格式的公式，然后将数据再复制，但这样仍然无法对数据的处理过程进行灵活复用。
    4.无法自动化
        数据分析要经过一个数据输入、处理、分析和输出的过程，这些都是由人工来进行操作，无法实现自动化
    """
    # 返回DataFrame
    pd.read_excel('team.xlsx')  # 默认读取第一个标签页Sheet
    pd.read_excel('path_to_file.xlsx', sheet_name='Sheet1')  # 指定Sheet
    # 从URL读取
    pd.read_excel('https://www.gairuo.com/file/data/dataset/team.xlsx')
    
    # 将多个df分不同sheet导入一个Excel文件中
    with pd.ExcelWriter('path_to_file.xlsx') as writer:
        df1.to_excel(writer, sheet_name='Sheet1')
        df2.to_excel(writer, sheet_name='Sheet2')


# 读取JSON
def _json():
    """
    JSON是互联网上非常通用的轻量级数据交换格式，是 HTTP 请求中数据的标准格式之一。
    Pandas 提供的 JSON 读取方法在解析网络爬虫数据时，可以极大地提高效率。
    Pandas 还提供了 pd.json_normalize(data) 方法来读取半结构化的JSON数据。
    """
    # data.json为同目录下的一个文件
    pd.read_json('data.json')
    # 可以解析一个JSON字符串，以下是从HTTP服务检测到的设备信息：
    jdata = '{"res":{"model":"iPhone","browser":"Safari","version":"604.1"},"status":200}'
    pd.read_json(jdata)


# 读取HTML
def _html():
    """
    pd.read_html() 函数可以接受 HTML 字符串、HTML 文件、URL，并将 HTML 中的 <table> 标签表格数据解析为 DataFrame。
    如返回有多个 df 的列表，则可以通过索引取第几个。
    如果页面里只有一个表格，那么这个列表就只有一个 DataFrame。
    此方法是 Pandas 提供的一个简单实用的实现爬虫功能的方法。
    
    # 需要安装 lxml 库
    """
    url = ""
    dfs = pd.read_html('https://www.gairuo.com/p/pandas-io')
    print(dfs[0])  # 查看第一个df
    # 读取网页文件，第一行为表头
    dfs = pd.read_html('data.html', header=0)
    # 第一列为索引
    dfs = pd.read_html(url, index_col=0)
    
    # 如果一个网页表格很多，可以指定元素来获取：
    # id='table'的表格，注意这里仍然可能返回多个
    dfs1 = pd.read_html(url, attrs={'id': 'table'})
    # dfs1[0]
    # class='sortable'
    dfs2 = pd.read_html(url, attrs={'class': 'sortable'})
    # 常用的参数与read_csv的基本相同。


# 读取剪贴板
def _clipboard():
    """
    剪贴板（Clipboard）是操作系统级的一个暂存数据的地方，它保存在内存中，可以在不同软件之间传递，非常方便。
    Pandas 支持读取剪贴板中的结构化数据，这就意味着我们不用将数据保存成文件，
    而可以直接从网页、Excel等文件中复制，然后从操作系统的剪贴板中读取，非常方便。
    """
    '''
    x y z
    a 1 2 3
    b 4 5 6
    c 7 8 9
    '''
    # 复制上边的数据，然后直接赋值
    cdf = pd.read_clipboard()
    # 变量cdf就是上述文本的DataFrame结构数据。read_clipboard的参数使用与read_csv完全一样。


# 读取SQL
def _sql():
    """
    Pandas需要引入 SQLAlchemy 库来支持 SQL，在 SQLAlchemy 的支持下，它可以实现所有常见数据库类型的查询、更新等操作。
    Pandas 连接数据库进行查询和更新的方法如下。
    
    read_sql_table(table_name, con[, schema, …])：把数据表里的数据转换成 DataFrame。
    read_sql_query(sql, con[, index_col, …])：用sql查询数据到 DataFrame 中。
    read_sql(sql, con[, index_col, …])：同时支持上面两个功能。
    DataFrame.to_sql(self, name, con[, schema, …])：把记录数据写到数据库里。
    """
    # 需要安装SQLAlchemy库
    from sqlalchemy import create_engine
    import pymysql
    # 创建数据库对象，SQLite内存模式
    
    # sqlalchemy引擎)
    user = 'root'
    host = '127.0.0.1'
    password = 'root'
    db = 'zjdata'
    port = 3306
    connstr = 'mysql+pymysql://{user}:{password}@{host}:{port}/{db}'.format(user=user,
                                                                            host=host,
                                                                            password=password,
                                                                            db=db,
                                                                            port=port)
    
    # pymysql引擎
    conn = pymysql.connect(
        host=host,
        user=user,
        password=password,
        database=db,
        charset="utf8"
    )
    
    engine = create_engine('sqlite:///:memory:')
    
    # 取出表名为data的表数据
    with engine.connect() as conn, conn.begin():
        data = pd.read_sql_table('data', conn)
    # data
    # 将数据写入
    data.to_sql('data', engine)
    # 大量写入
    data.to_sql('data_chunked', engine, chunksize=1000)
    # 使用SQL查询
    pd.read_sql_query('SELECT * FROM data', engine)
